using AiQiuQuan.Sport.Model.Models;
using AiQiuQuan.Sport.Core;
using AiQiuQuan.Sport.WebApi.Entities;
using AiQiuQuan.Sport.WebApi.Repositories;
using Microsoft.EntityFrameworkCore;
using AiQiuQuan.Sport.Model.Enums;
using AiQiuQuan.Sport.WebApi.Core;

namespace AiQiuQuan.Sport.WebApi.Services.Impl
{
    /// <summary>
    /// 活动评论管理
    /// </summary>
    public class CommentService : ICommentService
    {
        private readonly ICurrentInfo _currentInfo;
        private readonly IBaseUserRepository _userRepository;
        private readonly IActivityCommentRepository _activityCommentRepository;
        private readonly IGameCommentRepository _gameCommentRepository;
        private readonly IBallCommentRepository _ballCommentRepository;
        private readonly IClubCommentRepository _clubCommentRepository;

        /// <summary>
        /// ctor
        /// </summary>
        public CommentService(
            ICurrentInfo currentInfo,
            IBaseUserRepository userRepository,
            IActivityCommentRepository activityCommentRepository,
            IGameCommentRepository gameCommentRepository,
            IBallCommentRepository ballCommentRepository,
            IClubCommentRepository clubCommentRepository)
        {
            _currentInfo = currentInfo;
            _userRepository = userRepository;
            _activityCommentRepository = activityCommentRepository;
            _gameCommentRepository = gameCommentRepository;
            _ballCommentRepository = ballCommentRepository;
            _clubCommentRepository = clubCommentRepository;
        }

        /// <summary>
        /// 分页查询
        /// </summary>
        public async Task<PageResult<CommentDto>> PageListAsync(CommentPageReqestDto request)
        {
            var result = PageResult.Empty<CommentDto>();
            IQueryable<CommentDto> queryable = null;
            switch (request.BusinessType)
            {
                case BusinessTypeEnum.Activity:
                    queryable = from comment in _activityCommentRepository.AsNoTracking()
                                join user in _userRepository.AsNoTracking()
                                on comment.UserId equals user.ID
                                where comment.ActivityId == request.BusinessId
                                select new CommentDto
                                {
                                    ID = comment.ID,
                                    ParentCommentId = comment.ParentCommentId,
                                    Content = comment.Content,
                                    UserId = comment.UserId,
                                    CreateTime = comment.CreateTime,
                                    UserName = user.U_NickName,
                                    HeadUrl = user.U_Headportrait,
                                    IsHaveSubComment = _activityCommentRepository.Any(m => comment.ID == m.ParentCommentId)
                                };
                    break;
                case BusinessTypeEnum.Ball:
                    queryable = from comment in _ballCommentRepository.AsNoTracking()
                                join user in _userRepository.AsNoTracking()
                                on comment.UserId equals user.ID
                                where comment.BallId == request.BusinessId
                                select new CommentDto
                                {
                                    ID = comment.ID,
                                    ParentCommentId = comment.ParentCommentId,
                                    Content = comment.Content,
                                    UserId = comment.UserId,
                                    CreateTime = comment.CreateTime,
                                    UserName = user.U_NickName,
                                    HeadUrl = user.U_Headportrait,
                                    IsHaveSubComment = _ballCommentRepository.Any(m => comment.ID == m.ParentCommentId)
                                };
                    break;
                case BusinessTypeEnum.Game:
                    queryable = from comment in _gameCommentRepository.AsNoTracking()
                                join user in _userRepository.AsNoTracking()
                                on comment.UserId equals user.ID
                                where comment.GameId == request.BusinessId
                                select new CommentDto
                                {
                                    ID = comment.ID,
                                    ParentCommentId = comment.ParentCommentId,
                                    Content = comment.Content,
                                    UserId = comment.UserId,
                                    CreateTime = comment.CreateTime,
                                    UserName = user.U_NickName,
                                    HeadUrl = user.U_Headportrait,
                                    IsHaveSubComment = _gameCommentRepository.Any(m => comment.ID == m.ParentCommentId)
                                };
                    break;
                case BusinessTypeEnum.Club:
                    queryable = from comment in _clubCommentRepository.AsNoTracking()
                                join user in _userRepository.AsNoTracking()
                                on comment.UserId equals user.ID
                                where comment.ClubId == request.BusinessId
                                select new CommentDto
                                {
                                    ID = comment.ID,
                                    ParentCommentId = comment.ParentCommentId,
                                    Content = comment.Content,
                                    UserId = comment.UserId,
                                    CreateTime = comment.CreateTime,
                                    UserName = user.U_NickName,
                                    HeadUrl = user.U_Headportrait,
                                    IsHaveSubComment = _activityCommentRepository.Any(m => comment.ID == m.ParentCommentId)
                                };
                    break;
            }

            queryable = request.ParentCommentId != null
                        ? queryable.Where(m => m.ParentCommentId == request.ParentCommentId)
                        : queryable.Where(m => m.ParentCommentId == null);
            result = await queryable.OrderByDescending(m => m.CreateTime).PageListAsync(request);
            return result;
        }

        /// <summary>
        /// 查询
        /// </summary>
        /// <param name="businessType">业务类型</param>
        /// <param name="id">评论id</param>
        public async Task<CommentDto> GetAsync(BusinessTypeEnum businessType, Guid id)
        {
            CommentDto result = null;
            switch (businessType)
            {
                case BusinessTypeEnum.Activity:
                    var activityQueryable = from comment in _activityCommentRepository.AsNoTracking()
                                            join user in _userRepository.AsNoTracking()
                                            on comment.UserId equals user.ID
                                            where comment.ID == id
                                            select new CommentDto
                                            {
                                                ID = comment.ID,
                                                ParentCommentId = comment.ParentCommentId,
                                                Content = comment.Content,
                                                UserId = comment.UserId,
                                                CreateTime = comment.CreateTime,
                                                UserName = user.U_NickName,
                                                HeadUrl = user.U_Headportrait
                                            };
                    result = await activityQueryable.FirstOrDefaultAsync();
                    break;
                case BusinessTypeEnum.Ball:
                    var ballQueryable = from comment in _ballCommentRepository.AsNoTracking()
                                        join user in _userRepository.AsNoTracking()
                                        on comment.UserId equals user.ID
                                        where comment.ID == id
                                        select new CommentDto
                                        {
                                            ID = comment.ID,
                                            ParentCommentId = comment.ParentCommentId,
                                            Content = comment.Content,
                                            UserId = comment.UserId,
                                            CreateTime = comment.CreateTime,
                                            UserName = user.U_NickName,
                                            HeadUrl = user.U_Headportrait
                                        };
                    result = await ballQueryable.FirstOrDefaultAsync();
                    break;
                case BusinessTypeEnum.Game:
                    var gameQueryable = from comment in _gameCommentRepository.AsNoTracking()
                                        join user in _userRepository.AsNoTracking()
                                        on comment.UserId equals user.ID
                                        where comment.ID == id
                                        select new CommentDto
                                        {
                                            ID = comment.ID,
                                            ParentCommentId = comment.ParentCommentId,
                                            Content = comment.Content,
                                            UserId = comment.UserId,
                                            CreateTime = comment.CreateTime,
                                            UserName = user.U_NickName,
                                            HeadUrl = user.U_Headportrait
                                        };
                    result = await gameQueryable.FirstOrDefaultAsync();
                    break;
                case BusinessTypeEnum.Club:
                    var clubQueryable = from comment in _clubCommentRepository.AsNoTracking()
                                        join user in _userRepository.AsNoTracking()
                                        on comment.UserId equals user.ID
                                        where comment.ID == id
                                        select new CommentDto
                                        {
                                            ID = comment.ID,
                                            ParentCommentId = comment.ParentCommentId,
                                            Content = comment.Content,
                                            UserId = comment.UserId,
                                            CreateTime = comment.CreateTime,
                                            UserName = user.U_NickName,
                                            HeadUrl = user.U_Headportrait
                                        };
                    result = await clubQueryable.FirstOrDefaultAsync();
                    break;
            }

            return result;
        }

        /// <summary>
        /// 新增
        /// </summary>
        public async Task<UnaryResult> AddAsync(CommentAddDto model)
        {
            switch (model.BusinessType)
            {
                case BusinessTypeEnum.Activity:
                    var activityComment = new ActivityComment
                    {
                        ActivityId = model.BusinessId,
                        UserId = _currentInfo.UserId,
                        ParentCommentId = model.ParentCommentId,
                        Content = model.Content,
                    };
                    await _activityCommentRepository.AddAsync(activityComment);
                    break;
                case BusinessTypeEnum.Ball:
                    var ballComment = new BallComment
                    {
                        BallId = model.BusinessId,
                        UserId = _currentInfo.UserId,
                        ParentCommentId = model.ParentCommentId,
                        Content = model.Content,
                    };
                    await _ballCommentRepository.AddAsync(ballComment);
                    break;
                case BusinessTypeEnum.Game:
                    var gameComment = new GameComment
                    {
                        GameId = model.BusinessId,
                        UserId = _currentInfo.UserId,
                        ParentCommentId = model.ParentCommentId,
                        Content = model.Content,
                    };
                    await _gameCommentRepository.AddAsync(gameComment);
                    break;
                case BusinessTypeEnum.Club:
                    var clubComment = new ClubComment
                    {
                        ClubId = model.BusinessId,
                        UserId = _currentInfo.UserId,
                        ParentCommentId = model.ParentCommentId,
                        Content = model.Content,
                    };
                    await _clubCommentRepository.AddAsync(clubComment);
                    break;
            }

            return UnaryResult.Succeed();
        }
    }
}
